package com.simulacra.model;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;

import com.simulacra.util.Utilities;
import com.simulacra.util.log.Logger;
/**
 * Clase que genera eventos de tipo {@link com.simulacra.model.SoccerEvent}
 * usando apoyo de la clase RangeTable
 * 
 */
public class SoccerEventGenerator implements EventGenerator {
	EventListener currentMonitor = null;
	Thread game = null;
	int eventAmountLimit =0 ;
	RangeTable table = null;
	RangeTable teamRangeAverageTable= null;
	RangeTableBuilder builder = null;
	NumberGenerator random = null;
	List<String> eventCatalog = null;
	List<String> playingTeamCatalog = null;
	String currentEventTeam= null;
	public SoccerEventGenerator (HashMap<String, Double> dataSource ,int loop) {
		this(dataSource, Utilities.getTeamData(dataSource), loop);
		
	}
	public SoccerEventGenerator (HashMap<String, Double> dataSource, HashMap<String, Double> teamData ,int loop) {
		Iterator<String> it= null;
		int length = 0;
		Object next= null;
		double [] average = null;
		double [] team = null;
		eventAmountLimit = loop;

		builder= new RangeTableBuilder();
		if (dataSource != null && (length= dataSource.size()) >0) {
			eventCatalog = new ArrayList<String>();
			it= dataSource.keySet().iterator();
			average = new double [length];
			for (int i=0; it.hasNext(); i++) {
				next = it.next();
				average[i] = ((Double)dataSource.get(next)).doubleValue();
				eventCatalog.add(next.toString());
			}
		}		

		table= builder.createRangeTable(average, team);
		setTeamData(teamData);
		random = new RandomNumberGenerator();
		game = new Thread(this);
	}
	
	public SoccerEventGenerator (File dataSource) {
		this (new HashMap<String, Double>(), 1);
	}
	public double [] setTeamData(HashMap<String, Double> teamData) {
		Iterator<String> it= null;
		int length = 0;
		double [] team = null;
		Object next= null;
		if (teamData != null && (length= teamData.size()) >0) {
			it= teamData.keySet().iterator();
			team = new double [length];
			playingTeamCatalog = new ArrayList<String>();
			for (int i=0; it.hasNext(); i++) {
				next = it.next();Logger.log(this, "adding " +next);
				playingTeamCatalog.add(next.toString());
				team[i] = ((Double)teamData.get(next)).doubleValue();// eventCatalog.add(next.toString());
			}
		}
		table.setTeamRange(team);
		return team;
	}

	public void addEventListener(EventListener monitor) {
		currentMonitor= monitor;


	}
	public void start() {

		game = new Thread(this);
		game.start();
	}

	public void run() {
		String methodName = "run () ";
		int indexEvent = 0;
		String eventName = "";
		boolean flag = true;
		int cycle=0;
		SimulacraEvent currentEvent = null;

		Logger.log(this, methodName + "["+ cycle+ "]");
		while (flag) {
			cycle++;// Logger.log(this, "team-"+ playingTeamCatalog.get(Integer.parseInt(getCurrentEventTeam())));

			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			indexEvent = applyEvent(table.getLocation(random.getNextNumber(), random.getNextNumber()) );
			eventName= eventCatalog.get(indexEvent -1);
			currentEvent = new SoccerEvent (eventName, playingTeamCatalog.get(Integer.parseInt(getCurrentEventTeam())), 0);

			if (currentMonitor == null) {
				Logger.log(this, "No Listener");
			} else {
				currentMonitor.eventThrow(this, currentEvent);
			}
			if (cycle==eventAmountLimit) flag= false;
		}
		currentMonitor.eventThrow(this, new SoccerEvent(SoccerEvent.END_EVENT_LABEL));

		
	}
	private int applyEvent (String location) {
		String index = "";
		String team = "";
		if (location != null && location.length() >0 ) {
			team= location.substring(0, 1);
			index= location.substring(2);
		}
		setCurrentEventTeam (team);
		return Integer.valueOf(index);
		
	}
	private void setCurrentEventTeam(String team) {
		currentEventTeam = team;
		// TODO Auto-generated method stub
		
	}	
	private String getCurrentEventTeam() {
		return getCurrentEventTeam(null) ;
		// TODO Auto-generated method stub
		
	}	
	private String getCurrentEventTeam(String defacto) {
		String value = null;
		if (defacto== null) {
			value= currentEventTeam;
		} else {
			value = defacto;
		}
		Logger.log(this, "team-"+ value);
		return value ;
		// TODO Auto-generated method stub
		
	}
	public static void main (String[] argument ) {
		HashMap<String, Double>  map = null;
		SoccerEventGenerator generator = null;
		map = new HashMap <String, Double> ();

		map.put(Team.VISIT_TEAM, new Double (0.2));
		map.put(Team.LOCAL_TEAM, new Double (0.8));
		map.put("Corner", new Double (0.1));
		map.put("Gol", new Double (0.05));
		map.put("Faul", new Double (0.3));
		map.put("Off Side", new Double (0.2));
		map.put("Amonestacion", new Double (0.1));
		map.put("Direct Shot", new Double (0.05));
		map.put("Band Throw", new Double (0.2));
		generator = new SoccerEventGenerator(map, 1);
		generator.addEventListener(null);
		generator.start();
		
	}

}
